FrameLib  0.1
Arbitrarily timed and sized frame-based DSP
FrameLib_Memory.h
Go to the documentation of this file.
1 
2 #ifndef FRAMELIB_MEMORY_H
3 #define FRAMELIB_MEMORY_H
4 
5 #include "tlsf.h"
6 #include "FrameLib_Threading.h"
7 
8 #include <vector>
9 #include <ctime>
10 #include <string>
11 
12 // The Global Allocator (adds threadsafety to the CoreAllocator)
13 
15 {
16 
17 private:
18 
19  // The Core Allocator (has no threadsafety)
20 
21  class CoreAllocator
22  {
23  // ************************************************************************************** //
24 
25  // Memory Pools
26 
27  struct Pool
28  {
29  Pool(void *mem, size_t size) : mUsedRecently(true), mTime(0), mSize(size), mPrev(NULL), mNext(NULL), mMem(mem) {}
30 
31  bool isFree() { return tlsf_pool_is_free(mMem); }
32 
33  bool mUsedRecently;
34  time_t mTime;
35  size_t mSize;
36  Pool *mPrev;
37  Pool *mNext;
38  void *mMem;
39  };
40 
41  // ************************************************************************************** //
42 
43  // Thread for Allocating System Memory
44 
45  class NewThread : public DelegateThread
46  {
47 
48  public:
49 
50  NewThread(CoreAllocator *allocator) : DelegateThread(Thread::kHighPriority), mAllocator(allocator) {}
51 
52  private:
53 
54  virtual void doTask() { mAllocator->addScheduledPool(); };
55 
56  CoreAllocator *mAllocator;
57  };
58 
59  // ************************************************************************************** //
60 
61  // Thread for Freeing System Memory
62 
63  class FreeThread : public TriggerableThread
64  {
65 
66  public:
67 
68  FreeThread(CoreAllocator *allocator) : TriggerableThread(Thread::kLowPriority), mAllocator(allocator) {}
69 
70  private:
71 
72  virtual void doTask() { mAllocator->destroyScheduledPool(); };
73 
74  CoreAllocator *mAllocator;
75  };
76 
77  // ************************************************************************************** //
78 
79  public:
80 
81  CoreAllocator();
82  ~CoreAllocator();
83 
84  // Allocate and deallocate memory (plus pruning)
85 
86  void *alloc(size_t size);
87  void dealloc(void *ptr);
88 
89  void prune();
90 
91  private:
92 
93  // Get a Pool Class a tlsf pool_t
94 
95  Pool *getPool(pool_t pool);
96 
97  // Pool Helpers
98 
99  static Pool *createPool(size_t size);
100  static void destroyPool(Pool *pool);
101  void linkPool(Pool *pool);
102  void unlinkPool(Pool *pool);
103  void poolToTop(Pool *pool);
104  void insertPool(Pool *pool);
105  void removePool(Pool *pool);
106 
107  // Scheduled creation/deletion
108 
109  void addScheduledPool();
110  void destroyScheduledPool();
111 
112  // Member Variables
113 
114  tlsf_t mTLSF;
115  Pool *mPools;
116 
117  size_t mOSAllocated;
118  size_t mAllocated;
119 
120  size_t mLastDisposedPoolSize;
121  FrameLib_AtomicPtr<Pool> mScheduledNewPool;
122  FrameLib_AtomicPtr<Pool> mScheduledDisposePool;
123  NewThread mAllocThread;
124  FreeThread mFreeThread;
125  };
126 
127  // ************************************************************************************** //
128 
129 public:
130 
131  // The Pruner uses RAII to lock the CoreAllocator allowing repeated deallocation followed by a prune with a single lock
132 
133  class Pruner
134  {
135 
136  public:
137 
138  Pruner(FrameLib_GlobalAllocator *allocator) : mAllocator(allocator)
139  {
140  mAllocator->mLock.acquire();
141  }
142 
144  {
145  mAllocator->mAllocator.prune();
146  mAllocator->mLock.release();
147  }
148 
149  void dealloc(void *ptr) { mAllocator->mAllocator.dealloc(ptr); }
150 
151  private:
152 
153  // Deleted
154 
155  Pruner(const Pruner&);
156  Pruner& operator=(const Pruner&);
157 
158  // Allocator
159 
160  FrameLib_GlobalAllocator *mAllocator;
161  };
162 
163  // ************************************************************************************** //
164 
165  // Constructor / Destructor
166 
169 
170  // Allocate / Deallocate Memory
171 
172  void *alloc(size_t size);
173  void dealloc(void *ptr);
174 
175  // Alignment Helpers
176 
177  static size_t getAlignment();
178  static size_t alignSize(size_t x);
179 
180 private:
181 
182  // Deleted
183 
186 
187  // Member Variables
188 
189  FrameLib_SpinLock mLock;
190  CoreAllocator mAllocator;
191 };
192 
193 // ************************************************************************************** //
194 
195 // The Local Allocator
196 
198 {
199  // Local Blocks (free memory in double linked list (using internal pointers))
200 
201  static const int numLocalFreeBlocks = 16;
202 
203  struct FreeBlock
204  {
205  FreeBlock() : mMemory(NULL), mSize(0), mPrev(NULL), mNext(NULL) {}
206 
207  void *mMemory;
208  size_t mSize;
209 
210  FreeBlock *mPrev;
211  FreeBlock *mNext;
212  };
213 
214  // ************************************************************************************** //
215 
216 public:
217 
218  // Named Storage Local to Each Context
219 
220  class Storage
221  {
223 
224  public:
225 
226  // Getters
227 
228  double *getData() const { return mData; }
229  unsigned long getSize() const { return mSize; }
230  const char *getName() const { return mName.c_str(); }
231 
232  // Resize the storage
233 
234  void resize(unsigned long size);
235 
236  protected:
237 
238  // Constructor / Destructor
239 
240  Storage(const char *name, FrameLib_LocalAllocator *allocator);
241  ~Storage();
242 
243  // Reference Counting
244 
245  void increment() { mCount++; }
246  unsigned long decrement() { return --mCount; }
247 
248  private:
249 
250  // Deleted
251 
252  Storage(const Storage&);
253  Storage& operator=(const Storage&);
254 
255  // Member Variables
256 
257  std::string mName;
258 
259  double *mData;
260  unsigned long mSize;
261  unsigned long mMaxSize;
262  unsigned long mCount;
263 
264  FrameLib_LocalAllocator *mAllocator;
265  };
266 
267  // ************************************************************************************** //
268 
269  // Constructor / Destructor
270 
273 
274  // Allocate / Deallocate Memory
275 
276  void *alloc(size_t size);
277  void dealloc(void *ptr);
278 
279  // Clear Local Free Blocks (and prune global allocator)
280 
281  void clear();
282 
283  // Alignment Helpers
284 
286  static size_t alignSize(size_t x) { return FrameLib_GlobalAllocator::alignSize(x); }
287 
288  // Register and Release Storage
289 
290  Storage *registerStorage(const char *name);
291  void releaseStorage(const char *name);
292 
293 private:
294 
295  // Deleted
296 
299 
300  // Find Storage by Name
301 
302  std::vector<Storage *>::iterator findStorage(const char *name);
303 
304  // Remove a Free Block after Allocation and Return the Pointer
305 
306  void *removeBlock(FreeBlock *block);
307 
308  // Member Variables
309 
310  FrameLib_GlobalAllocator *mAllocator;
311 
312  FreeBlock mFreeLists[numLocalFreeBlocks];
313  FreeBlock *mTail;
314 
315  std::vector <Storage *> mStorage;
316 };
317 
318 #endif
Pruner(FrameLib_GlobalAllocator *allocator)
Definition: FrameLib_Memory.h:138
~FrameLib_LocalAllocator()
Definition: FrameLib_Memory.cpp:324
~FrameLib_GlobalAllocator()
Definition: FrameLib_Memory.h:168
double * getData() const
Definition: FrameLib_Memory.h:228
static size_t getAlignment()
Definition: FrameLib_Memory.cpp:261
Definition: FrameLib_Threading.h:124
void dealloc(void *ptr)
Definition: FrameLib_Memory.cpp:253
const char * getName() const
Definition: FrameLib_Memory.h:230
void increment()
Definition: FrameLib_Memory.h:245
void clear()
Definition: FrameLib_Memory.cpp:373
static size_t getAlignment()
Definition: FrameLib_Memory.h:285
FrameLib_LocalAllocator(FrameLib_GlobalAllocator *allocator)
Definition: FrameLib_Memory.cpp:309
void dealloc(void *ptr)
Definition: FrameLib_Memory.h:149
Definition: FrameLib_Threading.h:284
Definition: FrameLib_Threading.h:242
~Pruner()
Definition: FrameLib_Memory.h:143
void * alloc(size_t size)
Definition: FrameLib_Memory.cpp:245
Definition: FrameLib_Threading.h:179
Definition: FrameLib_Memory.h:14
static size_t alignSize(size_t x)
Definition: FrameLib_Memory.h:286
Storage * registerStorage(const char *name)
Definition: FrameLib_Memory.cpp:392
void releaseStorage(const char *name)
Definition: FrameLib_Memory.cpp:406
Definition: FrameLib_Memory.h:197
static size_t alignSize(size_t x)
Definition: FrameLib_Memory.cpp:266
Definition: FrameLib_Threading.h:179
unsigned long getSize() const
Definition: FrameLib_Memory.h:229
unsigned long decrement()
Definition: FrameLib_Memory.h:246
Definition: FrameLib_Memory.h:220
Definition: FrameLib_Memory.h:133
FrameLib_GlobalAllocator()
Definition: FrameLib_Memory.h:167